package com.star.security.authentication;

import com.star.security.user.UserDetails;

import java.io.Serializable;

/**
 * 身份验证
 *
 * @author yangzj
 */
public interface Authentication extends Principal, Serializable {

    /**
     * 要进行身份验证的主体的身份。对于使用用户名和密码的身份验证请求，这将是用户名。
     * 调用方应填充身份验证请求的主体。AuthenticationManager 实现通常会返回一个包含更丰富信息的 Authentication 作为供应用程序使用的主体。
     * 许多身份验证提供程序将创建一个 UserDetails 对象作为主体。返回：正在认证的主体或认证后的认证主体。
     *
     * @return {@link Object}
     */
    Object getPrincipal();

    /**
     * 设置主体的身份
     *
     * @param principal 主体的身份
     */
    void setPrincipal(Object principal);

    /**
     * 证明主体正确的凭据。这通常是密码，但可以是与 AuthenticationManager 相关的任何内容。调用方应填充凭据。返回值：证明委托人身份的凭据
     *
     * @return {@link Object}
     */
    Object getCredentials();

    /**
     * 存储有关身份验证请求的其他详细信息。这些可能是 IP 地址、证书序列号等。返回：有关身份验证请求的其他详细信息，如果未使用，则返回 null
     *
     * @return {@link UserDetails}
     */
    Object getDetails();

    /**
     * 用于指示 AbstractSecurityInterceptor 是否应向 AuthenticationManager 提供身份验证令牌。
     * 通常，AuthenticationManager（或者更常见的是，其 AuthenticationProviders 之一）将在身份验证成功后返回不可变的身份验证令牌，
     * 在这种情况下，该令牌可以安全地返回 true 到此方法。返回 true 将提高性能，
     * 因为不再需要为每个请求调用 AuthenticationManager。
     * 出于安全原因，此接口的实现在从此方法返回 true 时应非常小心，除非它们是不可变的，或者有某种方法可以确保属性自原始创建以来未更改。
     * 不需要再次向 AuthenticationManager 提供令牌以进行重新身份验证，则返回 true。
     */
    boolean isAuthenticated();

    /**
     * 有关完整说明，请参见 isAuthenticated（）。实现应始终允许使用 false 参数调用此方法，
     * 因为各种类都使用它来指定不应信任的身份验证令牌。
     * 如果实现希望拒绝具有 true 参数的调用（这将指示身份验证令牌受信任 - 潜在的安全风险），
     * 则实现应引发 IllegalArgumentException。
     * Params： isAuthenticated – 如果令牌应受信任（这可能会导致异常），则为 true，如果令牌不应受信任，则为 false
     * 抛出：IllegalArgumentException – 如果由于实现不可变或实现自己的 isAuthenticated（）
     * 替代方法而拒绝使身份验证令牌受信任（通过传递 true 作为参数）
     */
    void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

    /**
     * 获取有效时间（秒）
     *
     * @return {@link long}
     */
    Long getExpiresIn();

    /**
     * 一个用户是否同时可以有多个登录
     *
     * @return boolean
     */
    Boolean getMultiEndpoint();

}
